import 一半异步_一半同步.Run;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Cache {
  
    private static final Map<String, Object> map;
  
    private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
  
    private static final Lock readLock = readWriteLock.readLock();
    private static final Lock writeLock = readWriteLock.writeLock();  

    static {  
        map = new HashMap<>();
    }
    public static class MyThread extends Thread{
        public MyThread(String name,Runnable runnable) {
            super(runnable,name);
        }
    }
  
    public static Object get(String key) {  
        readLock.lock();  
        try {
            System.out.println("读取value");
            System.out.println(System.currentTimeMillis());
            Thread.sleep(1000);
            System.out.println(System.currentTimeMillis());
            System.out.println("耗时1000");
            System.out.println(System.currentTimeMillis());
            return map.get(key);  
        } catch (InterruptedException interruptedException) {
            interruptedException.printStackTrace();
            return map.get(key);
        } finally {
            readLock.unlock();  
        }  
    }  
  
    public static Object put(String key, Object value) {  
        writeLock.lock();  
        try {

            System.out.println("设置value");
            System.out.println(System.currentTimeMillis());
            Thread.sleep(100);
            System.out.println(System.currentTimeMillis());
            System.out.println("耗时100");

            return map.put(key, value);
        } catch (InterruptedException interruptedException) {
            interruptedException.printStackTrace();
            return map.put(key, value);
        } finally {
            writeLock.unlock();  
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Runnable write = () -> put("a","value");
        Runnable read = () -> get("a");

        MyThread a1 = new MyThread("read1",read);
        MyThread w1 = new MyThread("write1",write);
        MyThread a2 = new MyThread("read2",read);
        MyThread w2 = new MyThread("write2",write);
        MyThread a3 = new MyThread("read3",read);
        MyThread w3 = new MyThread("write3",write);
        w1.start();
        TreeMap treeMap = new TreeMap();
        a1.start();
        a2.start();
        a3.start();
        w2.start();
        w3.start();
        Thread.currentThread().join(1000);

    }

}
